package main

import (
	// "fmt"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
	"strconv"
	// "strings"
	"sync"
)

var (
	divReg   = regexp.MustCompile(`<!-- 文字过长时会出现省略号，所以要为其标签加上title值 -->([\S\s]*?)<div class="pop-action f-cb js-rmodule" style="display:none;">`)
	nameReg  = regexp.MustCompile(`hidefocus="true" title="([\S\s]*?)" target="_blank"`)
	addrReg  = regexp.MustCompile(`<li>([^<>][\S\s]*?)<span class="w-icon w-icon20 icon-addr"></span></li>`)
	phoneReg = regexp.MustCompile(`<li>(\d*-*\d*?)<span class="w-icon w-icon20 icon-tel"></span></li>`)
	savePath = ""
)

var spider sync.WaitGroup

type company struct {
	Name  string
	Addr  string
	Phone string
}

func (com *company) compile() string {
	return com.Name + "," + com.Addr + "," + com.Phone + "\n"
}

func main() {
	// 获取输入的地址
	x := "1"
	y := "904"
	fileNm := "data.csv"
	if len(os.Args) > 3 {
		x = os.Args[1]
		y = os.Args[2]
		fileNm = os.Args[3]
	}
	url := "http://114.163.com/search/" + x + "/" + y + "/?q=&s=20&from=pager&p="
	p, _ := os.Getwd()
	savePath = p + "/data/" + fileNm

	for i := 0; i < 100; i++ {
		go getData(url + strconv.Itoa(i))
		spider.Add(1)
	}
	spider.Wait()
}

func httpGet(url string) []byte {
	resp, err := http.Get(url)
	if err != nil {
		return nil
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil
	}
	return body
}

func getData(url string) {
	defer spider.Done()
	d := httpGet(url)
	if d == nil {
		return
	}
	path := savePath
	divs := divReg.FindAllStringSubmatch(string(d), 30000)
	s := ""
	for _, val := range divs {
		com := new(company)
		name := nameReg.FindAllStringSubmatch(val[1], 2000)
		for _, v := range name {
			com.Name = v[1]
		}
		addr := addrReg.FindAllStringSubmatch(val[1], 2000)
		for _, v := range addr {
			com.Addr = v[1]
		}
		tel := phoneReg.FindAllStringSubmatch(val[1], 500)
		for _, v := range tel {
			com.Phone = v[1]
		}
		s = s + com.compile()
	}
	_, pathErr := os.Stat(path)
	if pathErr == nil {
		f, e := os.OpenFile(path, os.O_APPEND, 0777)
		defer f.Close()
		if e == nil {
			f.WriteString(s)
		}
	} else {
		f, e := os.Create(path)
		defer f.Close()
		if e == nil {
			f.WriteString(s)
		}
	}
}
